package usercenter

import (
	"context"
	"fmt"
	"github.com/zeromicro/go-zero/core/logx"
	"github.com/zeromicro/go-zero/core/stores/cache"
	"github.com/zeromicro/go-zero/core/stores/sqlc"
	"github.com/zeromicro/go-zero/core/stores/sqlx"
	"go.uber.org/zap"
	"navi-mumbai/common/gensql"
	"time"
)

var _ UserInviteOrderFlowModel = (*customUserInviteOrderFlowModel)(nil)

type (
	// UserInviteOrderFlowModel is an interface to be customized, add more methods here,
	// and implement the added methods in customUserInviteOrderFlowModel.
	UserInviteOrderFlowModel interface {
		userInviteOrderFlowModel
		SumOrderAmount(ctx context.Context, pid int64, rebateType int64, start, end *time.Time) (int64, error)
		Find(ctx context.Context, pid int64, rebateType int64, returntype int64, moneyAmount int64, startTime, endTime *time.Time, pageNo, pageSize int64) ([]*UserInviteOrderFlow, error)
		Count(ctx context.Context, pid int64, rebateType int64, returntype int64, moneyAmount int64, startTime, endTime *time.Time) (int64, error)
	}

	customUserInviteOrderFlowModel struct {
		*defaultUserInviteOrderFlowModel
		genSql *gensql.GenSql
		logx.Logger
	}
)

func (m *customUserInviteOrderFlowModel) Find(ctx context.Context, pid int64, rebateType int64, returntype int64, moneyAmount int64, startTime, endTime *time.Time, pageNo, pageSize int64) ([]*UserInviteOrderFlow, error) {
	query := fmt.Sprintf("select %s from %s ", userInviteOrderFlowRows, m.table)
	m.genSql.InitSql(query)
	if pid != 0 {
		m.genSql = m.genSql.Where("pid = ?", pid)
	}
	if rebateType != 0 {
		m.genSql = m.genSql.Where("rebate_type = ?", rebateType)
	}
	if returntype != 0 {
		m.genSql = m.genSql.Where("type = ?", returntype)
	}
	if moneyAmount > 0 {
		m.genSql = m.genSql.Where("money_amount >= ?", moneyAmount)
	}

	if startTime != nil {
		m.genSql = m.genSql.Where("create_time >= ?", startTime)
	}
	if endTime != nil {
		m.genSql = m.genSql.Where("create_time <= ?", endTime)
	}
	// 分页
	if pageNo < 1 {
		pageNo = 1
	}
	if pageSize <= 0 {
		pageSize = 10
	}
	q, v, err := m.genSql.OrderBy("create_time desc").Limit(uint64(pageSize)).Offset(uint64((pageNo - 1) * pageSize)).ToSql()
	if err != nil {
		m.Logger.Errorf("err == ", zap.Error(err))
		return nil, err
	}
	var list []*UserInviteOrderFlow
	err = m.QueryRowsNoCacheCtx(ctx, &list, q, v...)
	if err != nil {
		m.Logger.Errorf("err == ", zap.Error(err))
		return nil, err
	}
	return list, nil
}

func (m *customUserInviteOrderFlowModel) Count(ctx context.Context, pid int64, rebateType int64, returntype int64, moneyAmount int64, startTime, endTime *time.Time) (int64, error) {
	query := fmt.Sprintf("select count(id) from %s ", m.table)
	m.genSql.InitSql(query)
	if pid != 0 {
		m.genSql = m.genSql.Where("pid = ?", pid)
	}
	if rebateType != 0 {
		m.genSql = m.genSql.Where("rebate_type = ?", rebateType)
	}
	if returntype != 0 {
		m.genSql = m.genSql.Where("type = ?", returntype)
	}
	if moneyAmount > 0 {
		m.genSql = m.genSql.Where("money_amount = ?", moneyAmount)
	}

	if startTime != nil {
		m.genSql = m.genSql.Where("create_time >= ?", startTime)
	}
	if endTime != nil {
		m.genSql = m.genSql.Where("create_time <= ?", endTime)
	}
	q, v, err := m.genSql.ToSql()
	if err != nil {
		m.Logger.Errorf("err == ", zap.Error(err))
		return 0, err
	}
	var cnt int64
	err = m.QueryRowNoCacheCtx(ctx, &cnt, q, v...)
	if err != nil {
		m.Logger.Errorf("err == ", zap.Error(err))
		return 0, err
	}
	return cnt, nil
}
func (m *customUserInviteOrderFlowModel) SumOrderAmount(ctx context.Context, pid int64, rebateType int64, start, end *time.Time) (int64, error) {
	q := fmt.Sprintf("select coalesce(sum(money_amount), 0) from %s ", m.table)
	m.genSql.InitSql(q)
	if start != nil {
		m.genSql = m.genSql.Where("create_time >= ?", start)
	}
	if end != nil {
		m.genSql = m.genSql.Where("create_time <= ?", end)
	}
	if pid != 0 {
		m.genSql = m.genSql.Where("pid = ?", pid)
	}
	if rebateType != 0 {
		m.genSql = m.genSql.Where("rebate_type = ?", rebateType)
	}
	query, args, err := m.genSql.ToSql()
	if err != nil {
		return 0, err
	}
	var resp int64
	err = m.QueryRowNoCacheCtx(ctx, &resp, query, args...)
	switch err {
	case nil:
		return resp, nil
	case sqlc.ErrNotFound:
		return 0, nil
	default:
		return 0, err
	}
}

// NewUserInviteOrderFlowModel returns a model for the database table.
func NewUserInviteOrderFlowModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) UserInviteOrderFlowModel {
	return &customUserInviteOrderFlowModel{
		defaultUserInviteOrderFlowModel: newUserInviteOrderFlowModel(conn, c, opts...),
		genSql:                          gensql.NewGenSql(),
		Logger:                          logx.WithDuration(time.Second),
	}
}
